/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package me.yobol.algorithm.basic.value;

/**
 * @author Yobol
 * 
 */
public class Bits {
    
    /**
     * 找出两个整型数据以二进制形式表达时位数不同的数量
     * 
     * ^异或运算：两个二进制数据中对应位不同结果为1，相同为0
     * Integer.toBinaryString(int)方法将int数据转换为二进制位字符串
     * 
     * @param m
     * @param n
     * @return 
     */
    public static int countBitsDiff1(int m,int n){
        int counter = 0;
        int diffOr = m ^ n;
        String diffOrString = Integer.toBinaryString(diffOr);
        for(int i = 0;i < diffOrString.length();i++){
            if(diffOrString.charAt(i) == '1'){
                counter++;
            }
        }
        return counter;
    }
    
    
    
    /**
     * 统计一个整数数据以二进制形式表达时1的位数
     * 
     * 使用二进制数据和1进行&逻辑与运算，可以得到二进制数据的最低位
     * 
     * >>  算术右移,signed,左侧补符号位
     * >>> 逻辑右移,unsigned，左侧补0
     * 例如，以8位表示的-2将是11111110（10000010原码 --有符号数在计算机中以补码形式存储，负数从原码变补码需“取反加一”--> 11111110补码）
     * 将它使用>>右移一位，将变成11111111，即-1
     * 将它使用>>>右移一位，将变成01111111，即127
     * 
     * @param n
     * @return 
     */
    public static int countBits2(int n) {
	int counter = 0;
        while(n != 0){
            if((n & 1) == 1){
                counter++;
            }
            n >>>= 1;
        }
        return counter;
    }
    
    /**
     * 找出两个整型数据以二进制形式表达时位数不同的数量
     * 
     * ^异或运算：两个二进制数据中对应位不同结果为1，相同为0
     * 
     * @param m
     * @param n
     * @return 
     */
    public static int countBitsDiff2(int m,int n){
        int diffOr = m ^ n;
        return countBits2(diffOr);
    }
    
    /**
     * 统计一个整数数据以二进制形式表达时1的位数
     * 
     * 如果一个整数不为0，那么这个整数至少有一位为1。
     * 如果我们把这个整数减1，那么处在最右边的1将变成0，原来在该1后面的所有0都将变成1(如果1后面还有0的话)。
     * 其余位将不受影响。
     * 
     * 
     * 例如：一个二进制数11100，减去1后得到11011（发现减1的结果是把最右边的一个1开始向右的所有位都取反了），
     * 和原来的数进行&逻辑与运算后，从原来整数最右边一个1那一位开始所有位都会变成0，得到11000
     * 那么一个整数的二进制形式有多少个1，就能进行多少次这样的运算
     * @param n
     * @return 
     */
    public static int countBits3(int n){
        int counter = 0;//统计一个整数diffOr含有多少个1
        while(n != 0){
            n = n & (n - 1);
            counter++;
         }
        return counter;
    }
    
    /**
     * 找出两个整型数据以二进制形式表达时位数不同的数量
     * 
     * @param m
     * @param n
     * @return 
     */
    public static int countBitsDiff3(int m,int n){
        int diffOr = m ^ n;//先将二者做异或运算，得到结果
        
        return countBits3(diffOr);
    }
    
    public static void main(String[] args) {
        //结果应为7
        System.out.println(countBitsDiff1(1999,2299));
        System.out.println(countBitsDiff2(1999,2299));
        System.out.println(countBitsDiff3(1999,2299));
    }
}
